/* **********************************************************************************
 *
 * Copyright (c) TMF.AscendedThemeKit.Unthemed.NET Project. All rights reserved.
 *
 * This source code is subject to terms and conditions of the Shared Source License
 * for TMF.AscendedThemeKit.Unthemed. A copy of the license can be found in the License.html file
 * at the root of this distribution. If you can not locate the Shared Source License
 * for TMF.AscendedThemeKit.Unthemed, please send an email to ascend_adm@hotmail.com.
 * By using this source code in any fashion, you are agreeing to be bound by
 * the terms of the Shared Source License for TMF.AscendedThemeKit.Unthemed.NET.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * **********************************************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace TMF.AscendedThemeKit.Unthemed.Windows.Forms
{
    /// <summary>
    /// Contains a collection of NavigationPage objects.
    /// </summary>
    public class NavigationPageCollection : ICollection, IEnumerable, IList, IList<NavigationPanePage>
    {
        private NavigationPane _owner;
        private ArrayList _list;

        /// <summary>
        /// Initializes a new instance of the NavigationPageCollection class.
        /// </summary>
        /// <param name="parent">NavigationPane. The NavigationPane that this collection belongs to.</param>
        public NavigationPageCollection(NavigationPane parent)
        {
            this._owner = parent;
            this._list = new ArrayList();

        }

        /// <summary>
        /// Gets the number of navigation pages in the collection.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Int32 . The number of navigation pages in the collection.
        /// </para>
        /// <para>
        /// This property is read-only. 
        /// </para>
        /// </value>
        public int Count
        {
            get
            {
                return this._list.Count;

            }

        }

        /// <summary>
        /// Gets a value indicating whether access to the collection is synchronized (thread safe).
        /// </summary>
        /// <value>
        /// <para>
        /// System.Boolean . true if access to the collection is synchronized (thread safe); otherwise, false. The default is false.
        /// </para>
        /// <para>
        /// This property is read-only. 
        /// </para>
        /// </value>
        public bool IsSynchronized
        {
            get
            {
                return this._list.IsSynchronized;

            }

        }

        /// <summary>
        /// Gets an object that can be used to synchronize access to the collection.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Object . An object that can be used to synchronize access to the collection.
        /// </para>
        /// <para>
        /// This property is read-only. 
        /// </para>
        /// </value>
        public object SyncRoot
        {
            get
            {
                return this._list.SyncRoot;

            }

        }

        /// <summary>
        /// Copies the entire collection to a compatible one-dimensional Array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="array">System.Array. The one-dimensional Array that is the destination of the elements copied from the collection. The Array must have zero-based indexing.</param>
        /// <param name="index">  System.Int32. The zero-based index in the array at which copying begins.</param>
        public void CopyTo(Array array, int index)
        {
            this._list.CopyTo(array, index);

        }

        /// <summary>
        /// Copies the entire collection to a compatible one-dimensional array of NavigationPanePages, starting at the specified index of the target array.
        /// </summary>
        /// <param name="array">NavigationPanePage. The one-dimensional array of NavigationPanePages that is the destination of the elements copied from the collection. The Array must have zero-based indexing.</param>
        /// <param name="arrayIndex">  System.Int32. The zero-based index in the array at which copying begins.</param>
        public void CopyTo(NavigationPanePage[] array, int arrayIndex)
        {
            this._list.CopyTo(array, arrayIndex);

        }

        /// <summary>
        /// Gets a value indicating whether the collection has a fixed size.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Boolean . true if the collection has a fixed size; otherwise, false. The default is false.
        /// </para>
        /// <para>
        /// This property is read-only. 
        /// </para>
        /// </value>
        public bool IsFixedSize
        {
            get
            {
                return false;

            }

        }

        /// <summary>
        /// Gets a value indicating whether the collection is read-only.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Boolean . true if the collection is read only; otherwise, false. The default is false.
        /// </para>
        /// <para>
        /// This property is read-only. 
        /// </para>
        /// </value>
        public bool IsReadOnly
        {
            get
            {
                return false;

            }

        }

        /// <summary>
        /// Gets or sets the element at the specified index.
        /// </summary>
        /// <param name="index">  System.Int32. The zero-based index of the element to get or set.</param>
        /// <returns>
        /// <para>
        /// System.Object . The element at the specified index.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </returns>
        object IList.this[int index]
        {
            get
            {
                return this[index];

            }

            set
            {
                this[index] = (NavigationPanePage)value;

            }

        }

        /// <summary>
        /// Adds an object to the end of the collection.
        /// </summary>
        /// <param name="value">  System.Object. The Object to be added to the end of the collection. The value can be null.</param>
        /// <returns>
        /// System.Int32 . The collection index at which the value has been added.
        /// </returns>
        int IList.Add(object value)
        {
            NavigationPanePage page = value as NavigationPanePage;
            int returnValue = this.Add(page);

            return returnValue;

        }

        /// <summary>
        /// Removes all elements from the collection.
        /// </summary>
        void IList.Clear()
        {
            for (int i = 0; i < this._list.Count; i++)
            {
                this._owner.PageRemoved(this[i]);

            }

            this.Clear();

        }

        /// <summary>
        /// Determines whether an element is in the collection.
        /// </summary>
        /// <param name="value">System.Object. The Object to locate in the collection. The value can be null. </param>
        /// <returns>
        /// System.Boolean . true if item is found in the collection; otherwise, false.
        /// </returns>
        public bool Contains(object value)
        {
            return this._list.Contains(value);

        }

        /// <summary>
        /// Determines whether an element is in the collection.
        /// </summary>
        /// <param name="item">NavigationPanePage. The NavigationPanePage to locate in the collection. The value can be null. </param>
        /// <returns>
        /// System.Boolean . true if item is found in the collection; otherwise, false.
        /// </returns>
        public bool Contains(NavigationPanePage item)
        {
            return this._list.Contains(item);

        }

        /// <summary>
        /// Searches for the specified Object and returns the zero-based index of the first occurrence within the entire collection.
        /// </summary>
        /// <param name="value">System.Object. The Object to locate in the collection. The value can be null.</param>
        /// <returns>
        /// System.Int32 . The zero-based index of the first occurrence of value within the entire collection, if found; otherwise, -1.
        /// </returns>
        public int IndexOf(object value)
        {
            return this._list.IndexOf(value);

        }

        /// <summary>
        /// Searches for the specified NavigationPanePage and returns the zero-based index of the first occurrence within the entire collection.
        /// </summary>
        /// <param name="item">NavigationPanePage. The NavigationPanePage to locate in the collection. The value can be null.</param>
        /// <returns>
        /// System.Int32 . The zero-based index of the first occurrence of value within the entire collection, if found; otherwise, -1.
        /// </returns>
        public int IndexOf(NavigationPanePage item)
        {
            return this._list.IndexOf(item);

        }

        /// <summary>
        /// Searches for the specified NavigationPanePage name and returns the zero-based index of the first occurrence within the entire collection.
        /// </summary>
        /// <param name="name">The NavigationPanePage name to locate in the collection. The value can be null.</param>
        /// <returns>
        /// System.Int32 . The zero-based index of the first occurrence of value within the entire collection, if found; otherwise, -1.
        /// </returns>
        public int IndexOf(string name)
        {
            NavigationPanePage page = null;

            for (int i = 0; i < this._list.Count; i++)
            {
                if (((NavigationPanePage)this._list[i]).Name == name)
                {
                    page = (NavigationPanePage)this._list[i];
                    break;

                }

            }

            if (page != null)
            {
                return this._list.IndexOf(page);

            }
            else
            {
                return -1;

            }

        }

        /// <summary>
        /// Inserts an element into the collection at the specified index.
        /// </summary>
        /// <param name="index">System.Int32. The zero-based index at which value should be inserted.</param>
        /// <param name="value">System.Object. The Object to insert. The value can be null.</param>
        void IList.Insert(int index, object value)
        {
            NavigationPanePage page = value as NavigationPanePage;

            this.Insert(index, page);

        }

        /// <summary>
        /// Removes the first occurrence of a specific object from the collection.
        /// </summary>
        /// <param name="value">System.Object. The Object to remove from the collection. The value can be null. </param>
        void IList.Remove(object value)
        {
            this.Remove((NavigationPanePage)value);

        }

        /// <summary>
        /// Removes the element at the specified index of the collection.
        /// </summary>
        /// <param name="index">System.Int32. The zero-based index of the element to remove.</param>
        void IList.RemoveAt(int index)
        {
            this.RemoveAt(index);

        }

        /// <summary>
        /// Returns an enumerator for the entire collection.
        /// </summary>
        /// <returns>
        /// System.Collections.IEnumerator . An IEnumerator for the entire collection.
        /// </returns>
        public IEnumerator GetEnumerator()
        {
            return this._list.GetEnumerator();

        }

        /// <summary>
        /// Adds an object to the end of the collection.
        /// </summary>
        /// <param name="item">NavigationPaneNavigationButton. The NavigationPaneNavigationButton to be added to the end of the collection. The value can be null.</param>
        /// <returns>
        /// System.Int32 . The collection index at which the value has been added.
        /// </returns>
        public int Add(NavigationPanePage item)
        {
            int index = -1;

            if (!this._list.Contains(item))
            {
                index = this._list.Add(item);
                ((NavigationPanePage)this._list[index]).ButtonDisplayOrder = index;

                if (string.IsNullOrEmpty(((NavigationPanePage)this._list[index]).Key))
                {
                    ((NavigationPanePage)this._list[index]).Key = ((NavigationPanePage)this._list[index]).Name;

                }

                this._owner.PageAdded(item);

            }
            else
            {
                index = this._list.IndexOf(item);

            }

            return index;

        }

        /// <summary>
        /// Adds the elements of an NavigationPage array to the end of the collection.
        /// </summary>
        /// <param name="items">NavigationPaneNavigationButton[]. The array of NavigationPaneNavigationButton to add to the end of the collection.</param>
        public void AddRange(NavigationPanePage[] items)
        {
            foreach (NavigationPanePage navigationButton in items)
            {
                this.Add(navigationButton);

            }

        }

        /// <summary>
        /// Removes the first occurrence of a specific object from the collection.
        /// </summary>
        /// <param name="item">NavigationPage. The NavigationPaneNavigationButton to remove from the collection. The value can be null. </param>
        public void Remove(NavigationPanePage item)
        {
            this.RemoveAt(this.IndexOf(item));

        }

        /// <summary>
        /// Removes the element at the specified index of the collection.
        /// </summary>
        /// <param name="index">System.Int32. The zero-based index of the element to remove.</param>
        public void RemoveAt(int index)
        {
            NavigationPanePage page = this[index];
            this._owner.PageRemoved(page);

            this._list.Remove(page);

        }

        /// <summary>
        /// Inserts an element into the collection at the specified index.
        /// </summary>
        /// <param name="index">System.Int32. The zero-based index at which value should be inserted.</param>
        /// <param name="item">NavigationPage. The NavigationPage to insert. The value can be null.</param>
        public void Insert(int index, NavigationPanePage item)
        {
            this._list.Insert(index, item);

            this._owner.PageAdded(item);

        }

        /// <summary>
        /// Removes all elements from the collection.
        /// </summary>
        public void Clear()
        {
            this._owner.ClearPages();
            this._list.Clear();

        }

        /// <summary>
        /// Gets or sets the element at the specified index.
        /// </summary>
        /// <param name="index">  System.Int32. The zero-based index of the element to get or set.</param>
        /// <returns>
        /// <para>
        /// NavigationPanePage . The element at the specified index.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </returns>
        public NavigationPanePage this[int index]
        {
            get
            {
                if (index == -1) return null;

                return (NavigationPanePage)this._list[index];

            }
            set
            {
                this._list[index] = value;

            }

        }


        #region ICollection<NavigationPanePage> Members

        void ICollection<NavigationPanePage>.Add(NavigationPanePage item)
        {
            this._list.Add(item);
            this._owner.PageAdded(item);

        }

        bool ICollection<NavigationPanePage>.Remove(NavigationPanePage item)
        {
            this.RemoveAt(this.IndexOf(item));

            return true;

        }

        #endregion

        #region IEnumerable<NavigationPanePage> Members

        IEnumerator<NavigationPanePage> IEnumerable<NavigationPanePage>.GetEnumerator()
        {
            for (int i = 0; i < this._list.Count; i++)
            {
                yield return (NavigationPanePage)this._list[i];

            }

        }

        #endregion

        /// <summary>
        /// Gets the total number of NavigationPanePages that are requesting to be displayed.
        /// </summary>
        public int DisplayCount
        {
            get
            {
                int returnValue = 0;

                for (int i = 0; i < this._list.Count; i++)
                {
                    if (((NavigationPanePage)this._list[i]).Visible && ((NavigationPanePage)this._list[i]).ButtonVisible) returnValue++;

                }

                return returnValue;

            }

        }

        /// <summary>
        /// Gets the total number of NavigationPanePages that are visible.
        /// </summary>
        public int VisibleCount
        {
            get
            {
                int returnValue = 0;

                for (int i = 0; i < this._list.Count; i++)
                {
                    if (((NavigationPanePage)this._list[i]).Visible) returnValue++;

                }

                return returnValue;

            }

        }

    }

}
